package com.tony.blog.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tony.blog.api.utils.Constant;
import com.tony.blog.api.utils.PageUtil;
import com.tony.blog.api.utils.QueryUtil;
import com.tony.blog.model.entity.SysDeptEntity;
import com.tony.blog.model.entity.SysUserEntity;
import com.tony.blog.model.entity.SysUserPostEntity;
import com.tony.blog.model.entity.SysUserRoleEntity;
import com.tony.blog.model.mapper.SysUserMapper;
import com.tony.blog.server.service.SysDeptService;
import com.tony.blog.server.service.SysUserPostService;
import com.tony.blog.server.service.SysUserRoleService;
import com.tony.blog.server.service.SysUserService;
import com.tony.blog.server.shiro.ShiroUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 *
 * @Title: SysUserServiceImpl
 * @Auther: 皮蛋布丁
 * @Date: 2021/07/13/21:47
 * @Description:
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements SysUserService {

    @Autowired
    private SysDeptService sysDeptService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysUserPostService sysUserPostService;

    /**
    * @Description: updatePassword 更新密码
    * @Param: [userId, oldPassword, newPassword]
    * @return: void
    * @Author: 皮蛋布丁
    * @Date: 2021/7/13 21:51
    */
    @Override
    public boolean updatePassword(Long userId, String oldPassword, String newPassword) {
        SysUserEntity entity = new SysUserEntity();
        entity.setPassword(newPassword);

        return this.update(entity,new QueryWrapper<SysUserEntity>().eq("user_id",userId).eq("password",oldPassword));
    }

    /**
    * @Description: queryPage 获取用户列表信息(分页)
    * @Param: [map]
    * @return: com.tony.pmp.common.utils.PageUtil
    * @Author: 皮蛋布丁
    * @Date: 2021/7/26 11:15
    */
    @Override
    public PageUtil queryPage(Map<String, Object> map) {
        String search = (map.get("username") != null)? (String) map.get("username") : "";
        IPage<SysUserEntity> iPage = new QueryUtil<SysUserEntity>().getQueryPage(map);
        QueryWrapper wrapper = new QueryWrapper<SysUserEntity>()
                .like(StringUtils.isNotBlank(search),"username",search.trim())
                .or(StringUtils.isNotBlank(search.trim()))
                .like(StringUtils.isNotBlank(search),"name",search.trim());
        IPage<SysUserEntity> resPage = this.page(iPage,wrapper);
        
        //获取用户所属部门、用户的岗位信息
        SysDeptEntity dept;
        for (SysUserEntity user : resPage.getRecords()) {
            try {
                dept = sysDeptService.getById(user.getDeptId());
                user.setDeptName((dept != null && StringUtils.isNotBlank(dept.getName()))? dept.getName() : "");
                String postName = sysUserPostService.getPostNameByUserId(user.getUserId());
                user.setPostName(postName);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return new PageUtil(resPage);
    }

    /**
    * @Description: saveUser 新增用户信息
    * @Param: [user]
    * @return: boolean
    * @Author: 皮蛋布丁
    * @Date: 2021/7/26 14:25
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveUser(SysUserEntity user) {
        if (this.getOne(new QueryWrapper<SysUserEntity>().eq("username",user.getUsername())) != null) {
            throw new RuntimeException("用户名已经存在！");
        }
        user.setCreateTime(new Date());
        //加密字符串
        String salt = RandomStringUtils.randomAlphanumeric(20); //20位字符数字的随机字符串
        String password = ShiroUtil.sha256(user.getPassword(),salt);    //加密
        user.setPassword(password);
        user.setSalt(salt);
        this.save(user);
        //用户角色信息的添加
        sysUserRoleService.saveOrUpdate(user.getUserId(),user.getRoleIdList());
        //用户岗位信息的添加
        sysUserPostService.saveOrUpdate(user.getUserId(),user.getPostIdList());
        return true;
    }

    /**
    * @Description: getInfo 根据id获取用户信息
    * @Param: [userId]
    * @return: com.tony.pmp.model.entity.SysUserEntity
    * @Author: 皮蛋布丁
    * @Date: 2021/7/26 21:26
    */
    @Override
    public SysUserEntity getInfo(Long userId) {
        SysUserEntity entity = this.getById(userId);
        //获取用户角色信息
        List<Long> roleIds = sysUserRoleService.queryRoleIdList(userId);
        entity.setRoleIdList(roleIds);
        //获取用户岗位信息
        List<Long> postIds = sysUserPostService.queryPostIdList(userId);
        entity.setPostIdList(postIds);
        return entity;
    }

    /**
    * @Description: updateUser 修改用户信息
    * @Param: [user]
    * @return: boolean
    * @Author: 皮蛋布丁
    * @Date: 2021/7/26 21:44
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateUser(SysUserEntity user) {
        SysUserEntity oldUser = this.getById(user.getUserId());
        if (oldUser == null) {
            return true;
        }
        if (!oldUser.getUsername().equals(user.getUsername())) {
            if (this.getOne(new QueryWrapper<SysUserEntity>().eq("username",user.getUsername())) != null) {
                throw new RuntimeException("修改后用户名已经存在！");
            }
        }
        if (StringUtils.isNotBlank(user.getPassword())) {
            String password = ShiroUtil.sha256(user.getPassword(), oldUser.getSalt());
            user.setPassword(password);
            //region 方式二、更新新的盐字段
            /*String newSalt = RandomStringUtils.randomAlphanumeric(20);
            String password = ShiroUtil.sha256(user.getPassword(),newSalt);
            user.setPassword(password);
            user.setSalt(newSalt);*/
            //endregion
        }
        this.updateById(user);
        //更新用户角色信息
        sysUserRoleService.saveOrUpdate(user.getUserId(),user.getRoleIdList());
        //更新用户岗位信息
        sysUserPostService.saveOrUpdate(user.getUserId(),user.getPostIdList());
        return true;
    }

    /**
    * @Description: deleteUser 删除用户信息
    * @Param: [ids]
    * @return: void
    * @Author: 皮蛋布丁
    * @Date: 2021/7/27 11:48
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(Long[] ids) {
        if (ids != null && ids.length > 0) {
            List<Long> userIds = Arrays.asList(ids);
            this.removeByIds(userIds);
            //region 方式一：mybatisplus
            /*for (Long userId : userIds) {
                sysUserRoleService.remove(new QueryWrapper<SysUserRoleEntity>().eq("user_id",userId));
                sysUserPostService.remove(new QueryWrapper<SysUserPostEntity>().eq("user_id",userId));
            }*/
            //endregion
            //region 方法二：java8
            userIds.stream().forEach(userId -> sysUserRoleService.remove(new QueryWrapper<SysUserRoleEntity>().eq("user_id",userId)));
            userIds.stream().forEach(userId -> sysUserPostService.remove(new QueryWrapper<SysUserPostEntity>().eq("user_id",userId)));
            //endregion
        }
    }

    /**
    * @Description: updatePwd 重置密码
    * @Param: [ids]
    * @return: void
    * @Author: 皮蛋布丁
    * @Date: 2021/7/27 15:26
    */
    @Override
    public void updatePwd(Long[] ids) {
        if (ids != null && ids.length > 0) {
            SysUserEntity entity;
            for (Long id : ids) {
                entity = new SysUserEntity();

                String salt = RandomStringUtils.randomAlphanumeric(20);
                String newPwd = ShiroUtil.sha256(Constant.DefaultPassword,salt);
                entity.setPassword(newPwd);
                entity.setSalt(salt);

                this.update(entity,new QueryWrapper<SysUserEntity>().eq("user_id",id));
            }
        }
    }
}
